#!/bin/bash
#   d-shlibmove -- move shared library files around for Debian packaging
#   Copyright (C) 2002, 2005 Junichi Uekawa
#
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program; if not, write to the Free Software
#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

# 2002 Apr 23. Created.
#   automatic packaging of libtool-created library packages.

# from d-shlibs package

set -e
set -o pipefail

eval "$(dpkg-architecture -s)"

getname() {
	local SONAMELIBNAME
	local SONAMEVERSION
	local SONAME
	SONAME="$1"
	SONAMELIBNAME=${SONAME/%.so*}
	SONAMEVERSION=${SONAME/#*.so.}
	case "$SONAMELIBNAME" in
	  *[0-9])
		RETURN="$SONAMELIBNAME-$SONAMEVERSION"
		;;
	  *)
		RETURN="$SONAMELIBNAME$SONAMEVERSION"
		;;
	esac
}

readlibnameinfo() {
	LIBNAME="$1"

	if [ -z "$1" ] || ! echo "$1" | grep ".so$" > /dev/null; then
		echo "$0: [$1] is not a valid shared library file name" >&2
		exit 1;
	fi

	if [ ! -h "$1" ]; then
		echo "$0: expected [$1] to be a symlink, but it is not" >&2
		exit 1;
	fi

	SONAME=$(set -o pipefail; "$DEB_HOST_GNU_TYPE-objdump" -p "$LIBNAME" \
	| sed -n 's/^.*SONAME *//p')
	getname "$SONAME"
	SONAMEPKGNAME=$(echo "$RETURN" | tr '[:upper:]_' '[:lower:]-')
	PK=$(basename "$1" | sed 's/\.so$//')
	PK_LOWER=$(echo "$PK" | tr '[:upper:]_' '[:lower:]-')
	REALSO=$(readlink -f "$LIBNAME")
}

check_line() {
	local PKGNAME="$1"
	local ENTRYLINE="$2"

	# Do not check for "Section: libs" in Package if it was defined in Source before
        if echo "$ENTRYLINE" | grep -qw libs ; then
                if awk '/^Source:/,/^$/{print}' "$CONTROL" \
                | perl -0 -pe 's/\n[ \t]+/ /g' \
                | grep -q "$ENTRYLINE" ; then
                        CHECK_ERROR=false
                        return
                fi
        fi
	if ! awk '/^Package:.*'"$PKGNAME"'/,/^$/{print}' "$CONTROL" \
	| perl -0 -pe 's/\n[ \t]+/ /g' \
	| grep "$ENTRYLINE" > /dev/null; then
		echo "E: line [$ENTRYLINE] not found in $CONTROL section for $PKGNAME"
		# set this error signifier to true
		CHECK_ERROR=true
	fi
}


echo "Library package automatic movement utility"

CONTROL=debian/control

execscript=$(mktemp)
INSTALLFILE_SHLPKG=$(mktemp)
INSTALLFILE_DEVPKG=$(mktemp)
cat > "$execscript" <<EOF
set -e
EOF

EXTRALIBS=()
SUFFIX=
DEVSUFFIX=
TRANSITIONSUFFIX=

DOIT=no
DEVUNVERSIONED=no
IGNORELIBDEP=no
INCLUDEA=yes
INCLUDELA=yes
MULTIARCH=no
while [ -n "$1" ]; do
	case "$1" in
	  --moveshl)
		echo "$2 $3" >> "$INSTALLFILE_SHLPKG"
		shift; shift; shift;
		;;
	  --movedev)
		echo "$2 $3" >> "$INSTALLFILE_DEVPKG"
		shift; shift; shift;
		;;
	  --movedevdoc)
		echo "$2 usr/share/doc/\${PKGDEV}" >> "$INSTALLFILE_DEVPKG"
		shift; shift;
		;;
	  --commit)
		DOIT=yes
		shift;
		;;
	  --multiarch)
		MULTIARCH=yes
		shift;
		;;
	  --extralib)
		EXTRALIBS+=("$2")
		shift; shift;
		;;
	  --shlibs-local)
		shift;
		SHLIBSLOCALVER="$1";
		shift;
		;;
	  --suffix)
		shift;
		SUFFIX="$1";
		shift;
		;;
	  --devsuffix)
		shift;
		DEVSUFFIX="$1";
		shift;
		;;
	  --devunversioned)
		DEVUNVERSIONED=yes
		shift;;
	  --ignorelibdep)
		IGNORELIBDEP=yes
		shift;;
	  --c102)
		TRANSITIONSUFFIX="c102"
		shift;;
	  --ldbl)
		TRANSITIONSUFFIX="ldbl"
		shift;;
	  --v5)
		TRANSITIONSUFFIX="v5"
		shift;;
	  --t64)
		TRANSITIONSUFFIX="t64"
		shift;;
	  --include-a)
		INCLUDEA=yes
		shift;;
	  --exclude-a)
		INCLUDEA=no
		shift;;
	  --include-la)
		INCLUDELA=yes
		shift;;
	  --exclude-la)
		INCLUDELA=no
		shift;;
	  --override)
		OVERRIDE[${#OVERRIDE[@]}]="$2"
		shift; shift;;
	  --|*)
		break;
		;;
	esac
done

# path/libxxxx.so.yyy.zz.zz
# ------------------------- REALSO (actual .so filename that is linked to)
#      -------------- SONAME
#      -------    --- SONAMEPKGNAME (lowercased for package name)
# --------------- $1
#      ---------- PK
#      ---------- PK_LOWER (lowercased for package name)

DEVLIB_TO_CHECK=()
for extralib in "${EXTRALIBS[@]}"; do
	readlibnameinfo "$extralib"
	DEVLIB_TO_CHECK+=("$extralib")
	if [ "$INCLUDEA" = "yes" ]; then
		echo "$(dirname "$extralib")/$PK.a usr/lib" >> "$INSTALLFILE_DEVPKG"
	fi
	if [ "$INCLUDELA" = "yes" ]; then
		echo "$(dirname "$extralib")/$PK.la usr/lib || true" >> "$INSTALLFILE_DEVPKG"
	fi
	echo "$(dirname "$extralib")/$PK.so usr/lib" >> "$INSTALLFILE_DEVPKG"
	echo "$(dirname "$REALSO")/$SONAME usr/lib" >> "$INSTALLFILE_SHLPKG"
	echo "$REALSO usr/lib" >> "$INSTALLFILE_SHLPKG"
done

DEVLIB_TO_CHECK+=("$1")
readlibnameinfo "$1"
if [ "$DEVUNVERSIONED" = "yes" ]; then
	PKGDEV="$PK_LOWER$DEVSUFFIX-dev"
else
	PKGDEV="$SONAMEPKGNAME$DEVSUFFIX-dev"
fi
PKGSHL="$SONAMEPKGNAME$SUFFIX$TRANSITIONSUFFIX"

INSTALLDIR="install -d -m 755"
echo "$INSTALLDIR debian/$PKGDEV/usr/lib" >> "$execscript"
echo "$INSTALLDIR debian/$PKGSHL/usr/lib" >> "$execscript"
if [ "$INCLUDEA" = "yes" ]; then
	echo "mv $(dirname "$1")/$PK.a debian/$PKGDEV/usr/lib" >> "$execscript"
fi
if [ "$INCLUDELA" = "yes" ]; then
	echo "mv $(dirname "$1")/$PK.la debian/$PKGDEV/usr/lib || true" >> "$execscript"
fi
echo "mv $(dirname "$1")/$PK.so debian/$PKGDEV/usr/lib" >> "$execscript"
echo "mv $(dirname "$REALSO")/$SONAME debian/$PKGSHL/usr/lib" >> "$execscript"
if [ "$(dirname "$REALSO")/$SONAME" != "$REALSO" ]; then
	echo "mv $REALSO debian/$PKGSHL/usr/lib" >> "$execscript"
fi
if [ -n "$SHLIBSLOCALVER" ]; then
	echo "echo \"$SONAMELIBNAME $SONAMEVERSION $PKGSHL (>= $SHLIBSLOCALVER)\" >> debian/shlibs.local" >> "$execscript"
fi

d-devlibdeps "${OVERRIDE[@]/#/--override=}" "debian/$PKGDEV.substvars" "${DEVLIB_TO_CHECK[@]}"

#do some definition for the file.
echo "PKGDEV=$PKGDEV" >> "$execscript"
echo "PKGSHL=$PKGSHL" >> "$execscript"

#do the extra files
while read -r A B; do
	echo "$INSTALLDIR debian/$PKGSHL/$B" >> "$execscript"
	echo "mv $A debian/$PKGSHL/$B" >> "$execscript"
done < "$INSTALLFILE_SHLPKG"
if [ "$INCLUDELA" = "no" ]; then
	sed -i -e '/^.*\.la usr\/lib || true$/d' "$INSTALLFILE_DEVPKG"
fi
while read -r A B; do
	echo "$INSTALLDIR debian/$PKGDEV/$B" >> "$execscript"
	echo "mv $A debian/$PKGDEV/$B" >> "$execscript"
done < "$INSTALLFILE_DEVPKG"

if [ "$MULTIARCH" = "yes" ]; then
	sed -i -e "s/usr\\/lib\\( || true\\)\\?$/usr\\/lib\\/$DEB_HOST_MULTIARCH\\1/" "$execscript"
fi

cat "$execscript"

# check the syntax of the control file.
CHECK_ERROR=false

if ! [ "$DEVUNVERSIONED" = "yes" ]; then
	check_line "$PKGDEV" "Provides:.*$PK_LOWER-dev"
	check_line "$PKGDEV" "Conflicts:.*$PK_LOWER-dev"
fi
check_line "$PKGSHL" 'Section: \(libs\|non-free/libs\)'
if [ -n "$SUFFIX" ]; then
	check_line "$PKGSHL" "Conflicts: $SONAMEPKGNAME"
fi
if [ -n "$TRANSITIONSUFFIX" ]; then
	check_line "$PKGSHL" "Conflicts: $SONAMEPKGNAME$SUFFIX"
fi
check_line "$PKGDEV" 'Section: \(devel\|libdevel\|non-free/libdevel\)'
if ! [ "$IGNORELIBDEP" = "yes" ]; then
	check_line "$PKGDEV" "Depends:.*$PKGSHL"
fi
check_line "$PKGSHL" "Depends:.*[$]{shlibs:Depends}"

if [ "$CHECK_ERROR" = "true" ]; then
	echo "Error occurred, aborting" >&2
	exit 1
fi

if [ "$DOIT" = "yes" ]; then
	sh "$execscript"
else
	echo "Dry-run. If you are satisfied, run with --commit"
	exit 2
fi
rm -f "$execscript" "$INSTALLFILE_DEVPKG" "$INSTALLFILE_SHLPKG"

exit 0
